home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS02.ADF
/
C
/
alib.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-05-30
|
11KB
|
397 lines
/*
* ALIB Rev. 1.0
* Amiga Object Module Librarian
* Programmed by Mike Schwartz
* (C)1985, MS Software, all rights reserved.
*
* Feel free to distribute this program on a no-charge basis.
*
* Use:
* ALIB option library filelist
* Where
* option may be one of the following:
* D = delete object modules from library
* R = replace object modules (or add if not defined)
* L = directory of library
* library is the name of the library file to be created or modified.
* if no .lib extension is provided on the command line, it is
* appended. Also note that a file library.dir is created for
* each library file and is managed by this program.
* filelist is a list of object module filenames separated by spaces
* or commas. Note that if .o is not present in the filenames,
* .o will be appended.
*/
#include "stdio.h"
#include "fcntl.h"
/*
* The following structure defines the records in the .dir file for
* the library.
*/
#define LD struct libdir_def
struct libdir_def {
char object_filename[80]; /* name of .o file */
long module_offset; /* offset of module in .lib file */
long module_size; /* size of module in bytes */
};
/*
* When the library is openned, each object module is read into memory
* and managed with the following structure.
*/
#define LL struct liblist_def
struct liblist_def {
struct libdir_def dir_entry; /* directory entry for module */
char *object_module; /* actual text of module */
LL *next; /* pointer to next in list */
};
/*
* external functions
*/
extern char *getmem();
extern long lseek();
/*
* Global variables
*/
LL *objlist=NULL; /* linked list of object modules */
char libname[80]; /* name of library file */
int libfd; /* file descriptor for library file */
char objname[80]; /* name of object file */
int objfd; /* file descriptor for object file */
char dirname[80]; /* name of directory file */
int dirfd; /* file descriptor for directory file */
char buf[512]; /* misc buffer */
char option; /* user selected option */
/*
* This function prints the help messages and exits.
*/
help() {
printf("Use:\n");
printf(" ALIB option library filelist \n");
printf("Where\n");
printf(" option may be one of the following:\n");
printf(" D = delete object modules from library\n");
printf(" R = replace object modules (or add if not defined) \n");
printf(" L = directory of library\n");
printf(" library is the name of the library file to be created or modified.\n");
printf(" if no .lib extension is provided on the command line, it is \n");
printf(" appended. Also note that a file library.dir is created for\n");
printf(" each library file and is managed by this program. \n");
printf(" filelist is a list of object module filenames separated by spaces\n");
printf(" or commas. Note that if .o is not present in the filenames, \n");
printf(" .o will be appended. \n");
exit(1);
}
/*
* The following function opens the library and directory file. If the
* file does not exist, then the user is asked if he wants to create it.
* If the library exists, then it is read in and built in a linked list.
*/
open_library() {
LL *lp; /* pointer to module node */
/*
* Open the library file and directory file.
*/
libfd = open(libname, O_RDONLY | O_RAW);
if (libfd == -1) {
/*
* Library does not exist, prompt user for creation.
*/
while (1) {
printf("%s does not exist, create it? (Y/N): ", libname);
gets(buf);
if (buf[0] == 'y' || buf[0] == 'Y')
return !0;
if (buf[0] == 'n' || buf[0] == 'N') {
printf("Alib abandoned\n");
exit(1);
}
}
}
dirfd = open(dirname, O_RDONLY | O_RAW);
if (dirfd == -1) {
printf("%s has been corrupted\n", dirname);
printf("Alib abandoned\n");
exit(1);
}
/*
* library and directory files are open, read in the library.
*/
while (1) {
/*
* Allocate a node to hold the object module.
*/
lp = (LL *)getmem(sizeof(LL));
if (lp == NULL) {
printf("Not enough memory.\nAlib abandoned\n");
exit(1);
}
/*
* Check for end of file.
*/
if (read(dirfd, (char *)&lp->dir_entry, sizeof(LD)) != sizeof(LD))
break;
/*
* Allocate a buffer to hold the object file image.
*/
lp->object_module = getmem(lp->dir_entry.module_size);
if (lp->object_module == NULL) {
printf("Not enough memory.\nAlib abandoned\n");
exit(1);
}
/*
* Read in the object module
*/
if (read(libfd, lp->object_module, lp->dir_entry.module_size) !=
lp->dir_entry.module_size) {
printf("Library file is corrupted.\nAlib abandoned\n");
exit(1);
}
/*
* Add module to linked list.
*/
lp->next = objlist;
objlist = lp;
}
/*
* Library has been read in ok. Close files and return.
*/
close(libfd);
close(dirfd);
printf("Library file read in ok\n");
}
/*
* The following function removes an object module from the linked list
* and frees up any memory used by it.
*/
kill_module(name)
char *name;
{
LL *lp;
LL *lp2;
if (objlist == NULL)
return 0;
strcpy(objname, name);
strcat(objname, ".o");
if (strcmp(objlist->dir_entry.object_filename, objname) == 0) {
lp = objlist->next;
rlsmem(objlist->object_module, objlist->dir_entry.module_size);
rlsmem((char *)objlist, sizeof(LL));
objlist = lp;
return !0;
}
for (lp = objlist; lp->next != NULL; lp=lp->next)
if (strcmp(lp->next->dir_entry.object_filename, objname) == 0) {
lp2 = lp->next;
lp->next = lp2->next;
rlsmem(lp2->object_module, lp2->dir_entry.module_size);
rlsmem((char *)lp2, sizeof(LL));
return !0;
}
return 0;
}
/*
* The following function
*/
add_module(name)
char *name;
{
LL *lp;
int len;
strcpy(objname, name);
strcat(objname, ".o");
printf("adding %s\n", objname);
/*
* Open the object file
*/
objfd = open(objname, O_RDONLY | O_RAW);
if (objfd == -1) {
printf("%s cannot be added\nAlib abandoned\n", objname);
exit(1);
}
/*
* Allocate a node to hold the file.
*/
lp = (LL *)getmem(sizeof(LL));
if (lp == NULL) {
printf("Not enough memory.\nAlib abandoned\n");
exit(1);
}
/*
* Initialize it.
*/
strcpy(lp->dir_entry.object_filename, objname);
lp->dir_entry.module_size = lseek(objfd, 0, 2);
printf("module size = %d\n", lp->dir_entry.module_size);
lseek(objfd, 0, 0);
/*
* Allocate the buffer to read the object module into.
*/
lp->object_module = getmem(lp->dir_entry.module_size);
if (lp->object_module == NULL) {
printf("Not enough memory.\nAlib abandoned\n");
exit(1);
}
/*
* Read in the file.
*/
if (read(objfd, lp->object_module, lp->dir_entry.module_size) !=
lp->dir_entry.module_size) {
printf("Library file is corrupted.\nAlib abandoned\n");
exit(1);
}
/*
* Add module to linked list.
*/
lp->next = objlist;
objlist = lp;
/*
* Close object file and return.
*/
close(objfd);
printf("%s added\n", name);
}
/*
* The following routine writes the library from memory and exits.
*/
close_library() {
LL *lp;
long file_position;
long length;
/*
* Open the library
*/
libfd = open(libname, O_CREAT | O_RAW | O_WRONLY);
if (libfd == -1) {
printf("Error openning %s for output\nAlib abandoned", libname);
exit(1);
}
dirfd = open(dirname, O_CREAT | O_RAW | O_WRONLY);
if (dirfd == -1) {
printf("Error openning %s for output\nAlib abandoned", dirname);
exit(1);
}
/*
* Write out the individual modules and directory records.
*/
file_position = 0;
for (lp = objlist; lp != NULL; lp = lp->next) {
length = write(libfd, lp->object_module, lp->dir_entry.module_size);
if (length != lp->dir_entry.module_size) {
printf("Error writing to library file\nAlib abandoned\n");
exit(1);
}
lp->dir_entry.module_offset = file_position;
file_position += length;
if (write(dirfd, (char *)&lp->dir_entry, sizeof(LD)) != sizeof(LD)) {
printf("Error writing to directory file\nAlib abandoned\n");
exit(1);
}
}
/*
* Close the library files
*/
close(libfd);
close(dirfd);
printf("library is %ld bytes\nAlib complete\n", file_position);
exit(0);
}
/*
* Main program.
*/
main(argc, argv)
int argc;
char *argv[];
{
int count;
printf("ALIB Rev. 1.0 \n");
printf("Amiga Object Module Librarian\n");
printf("Programmed by Mike Schwartz\n");
printf("(C)1985 MS Software, all rights reserved\n");
/*
* check for command line parameters present.
*/
if (argc < 3)
help();
/*
* setup the option and filenames
*/
option = argv[1][0];
strcpy(libname, argv[2]);
strcpy(dirname, argv[2]);
strcat(libname, ".lib");
strcat(dirname, ".dir");
if (option == 'l' || option == 'L') {
directory();
exit(0);
}
if (option != 'd' && option != 'D' && option != 'r' && option != 'R')
help();
/*
* Open the library file
*/
open_library();
for (count = 3; count < argc; count++) {
switch(option) {
case 'd':
case 'D':
printf("deleting %s from library\n", argv[count]);
if (!kill_module(argv[count]))
printf("%s not defined in library\n", argv[count]);
else
printf("deleted.\n");
break;
case 'r':
case 'R':
kill_module(argv[count]);
add_module(argv[count]);
break;
}
}
close_library();
}
directory() {
LD d_entry;
int count;
int bytes;
dirfd = open(dirname, O_RDONLY | O_RAW);
if (dirfd == -1) {
printf("%s not found\n", dirname);
exit(1);
}
printf("Directory of library %s\n", libname);
printf("Module Name Size Offset\n");
count = bytes = 0;
while (read(dirfd, (char *)&d_entry, sizeof(LD)) == sizeof(LD)) {
printf("%-30.30s %-6d %-6d\n", d_entry.object_filename,
d_entry.module_size, d_entry.module_offset);
count++;
bytes += d_entry.module_size;
}
printf("Library consists of %d entries totalling %d bytes\n", count,
bytes);
close(dirfd);
}